# -*- coding: utf-8 -*-
#
# File: Reuniao.py
#
# Copyright (c) 2006 by IBICT
# Generator: ArchGenXML Version 1.5.0
#            http://plone.org/products/archgenxml
#
# GNU General Public License (GPL)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
#

__author__ = """IBICT <cadu@ibict.br>"""
__docformat__ = 'plaintext'

from AccessControl import ClassSecurityInfo
from Products.Archetypes.atapi import *
from Products.Archetypes.SQLStorage import *
from Products.SIGFS.config import *

##code-section module-header #fill in your manual code here
from Acquisition import aq_parent, aq_inner
from email.MIMEText import MIMEText
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.Message import Message
from Products.SIGFS.htmlrender import renderHTML
from Products.Archetypes import transaction
from Products.CMFCore.utils import getToolByName
##/code-section module-header

schema = Schema((

    StringField(
        name='numero',
        widget=StringWidget(
            label="Número da Reunião",
            description="Informe o número que identificará a Reunião.",
            label_msgid='SIGFS_label_numero',
            description_msgid='SIGFS_help_numero',
            i18n_domain='SIGFS',
        ),
        serchable="1",
        required=1,
        accessor="Id"
    ),

    DateTimeField(
        name='data_inicio',
        default="DateTime()",
        widget=CalendarWidget(
            label="Data da Reunião",
            description="Informe a data e hora que será realizada a Reunião.",
            format="%d/%m/%Y",
            label_msgid='SIGFS_label_data_inicio',
            description_msgid='SIGFS_help_data_inicio',
            i18n_domain='SIGFS',
        ),
        serchable="1",
        required=1,
        accessor="start"
    ),

    StringField(
        name='local',
        serchable="1",
        required=1,
        widget=StringWidget(
            label="Local da Reunião",
            description="Informe onde será realizada a Reunião.",
            label_msgid='SIGFS_label_local',
            description_msgid='SIGFS_help_local',
            i18n_domain='SIGFS',
        )
    ),

    StringField(
        name='tipo_reuniao',
        serchable="1",
        enforceVocabulary=1,
        widget=SelectionWidget(
            label="Tipo da Reunião",
            description="Selecione qual é o tipo da Reunião, extraordinária ou ordinária.",
            format="select",
            label_msgid='SIGFS_label_tipo_reuniao',
            description_msgid='SIGFS_help_tipo_reuniao',
            i18n_domain='SIGFS',
        ),
        vocabulary='getTiposReuniao',
        required=1
    ),

    BooleanField(
        name='reuniao_comite',
        index="FieldIndex",
        serchable="1",
        widget=BooleanWidget(
            label="Reunião do Comitê Gestor",
            description="Selecione este campo se esta será uma Reunião do Comitê Gestor, depois de publicada ela aparecerá na Agenda dos Fundos Setoriais do Portal.",
            label_msgid='SIGFS_label_reuniao_comite',
            description_msgid='SIGFS_help_reuniao_comite',
            i18n_domain='SIGFS',
        )
    ),

    DateTimeField(
        name='prazo_pendencia_reuniao',
        default="DateTime()",
        serchable="1",
        required=1,
        widget=CalendarWidget(
            label="Prazo de pendência",
            description="Informe a data durante a qual serão inseridos os comentários sobre a pauta da Reunião, antes de publicá-la. Esta data deve ser menor que a data de realização da Reunião.",
            format="%d/%m/%Y",
            date_only="1",
            show_hm=False,
            label_msgid='SIGFS_label_prazo_pendencia_reuniao',
            description_msgid='SIGFS_help_prazo_pendencia_reuniao',
            i18n_domain='SIGFS',
        )
    ),

    TextField(
        name='pauta',
        allowable_content_types=('text/plain', 'text/structured', 'text/html', 'application/msword',),
        serchable="1",
        default_output_type='text/html',
        widget=RichWidget(
            label="Pauta",
            description="Descreva a pauta da Reunião. A pauta será enviada aos convidados e convocados para que saibam do que se trata a mesma.",
            label_msgid='SIGFS_label_pauta',
            description_msgid='SIGFS_help_pauta',
            i18n_domain='SIGFS',
        ),
        required=1
    ),

    LinesField(
        name='convocados',
        widget=InAndOutWidget(
            label="Convocados",
            description="Selecione os membros do Comitê Gestor que serão convocados para a Reunião. Eles serão os revisores da pauta e acompanharão a Reunião.",
            label_msgid='SIGFS_label_convocados',
            description_msgid='SIGFS_help_convocados',
            i18n_domain='SIGFS',
        ),
        serchable="1",
        multiValued=1,
        vocabulary='listConvocados'
    ),

    LinesField(
        name='convidados',
        widget=InAndOutWidget(
            label="Convidados e Técnicos",
            description="Escolha quais usuários serão os técnicos e convidados para a Reunião.",
            label_msgid='SIGFS_label_convidados',
            description_msgid='SIGFS_help_convidados',
            i18n_domain='SIGFS',
        ),
        serchable="1",
        multiValued=1,
        vocabulary='listConvidados'
    ),

),
)

##code-section after-local-schema #fill in your manual code here
##/code-section after-local-schema

Reuniao_schema = BaseFolderSchema.copy() + \
    schema.copy()

##code-section after-schema #fill in your manual code here
##/code-section after-schema

class Reuniao(BaseFolder):
    """
    """
    security = ClassSecurityInfo()
    __implements__ = (getattr(BaseFolder,'__implements__',()),)

    # This name appears in the 'add' box
    archetype_name = 'Reunião'

    meta_type = 'Reuniao'
    portal_type = 'Reuniao'
    allowed_content_types = ['Ata']
    filter_content_types = 1
    global_allow = 0
    content_icon = 'topic_icon.gif'
    immediate_view = 'base_view'
    default_view = 'reuniao_view'
    suppl_views = ()
    typeDescription = "Agendamento de Reunião com os membros do Comitê Gestor, convidados e técnicos de outros Fundos Setoriais. Antes de ser publicada, a Reunião passará por uma revisão, os convocados e convidados receberão um email com um link para que possam ver a pauta antes da Reunião. Somente os convocados podem adicionar comentários sobre a pauta sugerindo ou não novos itens. O Secretário Técnico é o único membro que pode alterar os dados da Reunião sugeridos pelos convocados. Depois de alterada, a Reunião será publicada e enviará um email aos participantes convocando-os. Esta Reunião constará na Agenda do Escritório e na Agenda do Portal se for indicada como Reunião do Comitê Gestor."
    typeDescMsgId = 'description_edit_reuniao'
    allow_discussion = 1


    actions =  (


       {'action': "string:${object_url}/reuniao_view",
        'category': "object",
        'id': 'view',
        'name': 'View',
        'permissions': ("View",),
        'condition': 'python:1'
       },


       {'action': 'string:${object_url}/folder_localrole_form',
        'category': "object",
        'id': 'sharing',
        'name': 'Sharing',
        'permissions': ("SIGFS: Add Reuniao",),
        'condition': 'python:1'
       },


    )

    _at_rename_after_creation = True

    schema = Reuniao_schema

    ##code-section class-header #fill in your manual code here
    ##/code-section class-header

    # Methods

    # Manually created methods

    security.declarePrivate('_renameAfterCreation')
    def _renameAfterCreation(self, check_auto_id=False):
        """Renomeia o objeto com id numérico sequencial de 6 casas decimais."""
	parent_ids = self.aq_inner.aq_parent.objectIds()
        try:
          new_id = 're'+'%0.4i' % len(parent_ids)
          # Usando o portal_factory tem que comitar a subtransacao
          transaction.savepoint(optimistic=True)
	  self.setId(new_id)
	except:
	  new_id = 're'+'%0.4i' % len(parent_ids) + str(random.randint(1,1000))
          # Usando o portal_factory tem que comitar a subtransacao
          transaction.savepoint(optimistic=True)
	  self.setId(new_id)

    def listConvocados(self):
        """
        Retorna a lista dos ids dos Convocados para a Reunião que estão no grupo
        ComiteGestor do EV em questão ."""
        portal_groups = getToolByName(self, 'portal_groups')
        members = []

        for info in self.computeRoleMap():
            if info.get('type') == 'group' and 'Reviewer' in info.get('acquired'):
                group_id = info.get('id')
                group = portal_groups.getGroupById(group_id)
                members = members + [member.getId() for member in group.getGroupMembers()]

        return members

    def end(self):
        """Retorna a data inicial para aparecer marcado no calendário somente
        o dia da publicação."""
        return self.start()

    def listConvidados(self):
        """Retorna a lista Convidados para a Reunião."""
        portal_membership = getToolByName(self, 'portal_membership')
        convocados = self.listConvocados()

        return [i for i in portal_membership.listMemberIds() if i not in convocados]

    def getContactEmail(self):
        """Get the default email address, that of the creating user"""
        portal_groups = getToolByName(self, 'portal_groups')
        members = []

        for info in self.computeRoleMap():
            if info.get('type') == 'group' and 'Member' in info.get('acquired'):
                group_id = info.get('id')
                group = portal_groups.getGroupById(group_id)
                return group.getProperty('email',)

    def sendNotificationEmail(self, addresses, subject, rstText):
        """Send a notification email"""
        portal_url  = getToolByName(self, 'portal_url')
        plone_utils = getToolByName(self, 'plone_utils')

        portal      = portal_url.getPortalObject()
        mailHost    = plone_utils.getMailHost()
        charset     = plone_utils.getSiteEncoding()
        toAddresses = addresses
        fromEmail = self.getContactEmail()

        if toAddresses is None:
            log('Cannot send notification email: email sender addresses or name not set')
            return

        email = MIMEMultipart('alternative')
        email.epilogue = ''

        textPart = MIMEText(rstText, 'plain', charset)
        email.attach(textPart)
        htmlPart = MIMEText(renderHTML(rstText), 'html', charset)
        email.attach(htmlPart)
        message = str(email)
        mailHost.send(message = message,
                              mto = toAddresses,
                              mfrom = fromEmail,
                              subject = subject)

    def listNomeConvocados(self):
        """Lista dos nomes dos Convocados"""
        portal_membership = getToolByName(self, 'portal_membership')
        ct = []
        for u in self.getConvocados():
            membro = portal_membership.getMemberById(u)
            contatos = membro.getProperty('fullname', '')
            ct.append(contatos)
        return ct

    def getSecretario(self):
        """Retorna o Secretário para incluir no email"""
        portal_membership = getToolByName(self, 'portal_membership')
        for info in self.computeRoleMap():
            if info.get('type') == 'user' and 'Manager' in info.get('acquired'):
                user_id = info.get('id')
                return user_id

    def getContatos(self):
        """Retorna o Presidente, Secretário Técnico e seus dados"""
        portal_membership = getToolByName(self, 'portal_membership')
        contatos = {}
        for u in self.listConvocados():
            membro = portal_membership.getMemberById(u)
            funcao = membro.getProperty('funcao', '')
            if funcao == 'Presidente':
                contatos['nome_presidente'] = membro.getProperty('fullname', '')

        secretario = self.getSecretario()
        st = portal_membership.getMemberById(secretario)
        contatos['nome_secretario'] = st.getProperty('fullname', '')
        contatos['email_secretario'] = st.getProperty('email', '')
        contatos['telefone_secretario'] = st.getProperty('telefone', '')

        return contatos

    def listNomeConvidados(self):
        """Lista dos nomes dos Convocados"""
        portal_membership = getToolByName(self, 'portal_membership')
        ct = []
        for u in self.getConvidados():
            membro = portal_membership.getMemberById(u)
            contatos = membro.getProperty('fullname', '')
            ct.append(contatos)
        return ct

    def sendReviewMail(self):
        """Quando a reunião é enviada para revisão, envia uma notificação por
        email para os convidados e convocados revisarem a pauta."""
        portal_membership = getToolByName(self, 'portal_membership')
        usuarios = self.getConvocados()
        usuarios = usuarios + self.getConvidados()
        contatos = self.getContatos()
        fundo = self.getFundo()

        subject = "Convocação para revisão da pauta da reunião"
        mailText = self.pauta_review_send_mail(self, reuniao=self, contatos=contatos, fundo=fundo)

        for u in usuarios:
            email = portal_membership.getMemberById(u).getProperty('email', '')
            if email: self.sendNotificationEmail(email, subject, mailText)

    def getTiposReuniao(self):
        """Retorna a lista de Tipos de Reunião."""
        portal_sigfs = getToolByName(self, 'portal_sigfs')
        result = []
        vocabulary = portal_sigfs.getVocab_tipo_reuniao()

        for item in vocabulary:
            parts = item.split(';')
            result.append([parts[0], parts[1]])

        return DisplayList(tuple(result))

    def getFundo(self):
        """Retorna o Fundo Setorial que está enviando o email"""
        ev = self.aq_inner.aq_parent
        fundo = ev.aq_inner.aq_parent
        return fundo.Title()

    def sendNotificationMail(self):
        """Quando a reunião é publicada, envia uma notificação por
        email para os convidados e convocados."""
        portal_membership = getToolByName(self, 'portal_membership')
        usuarios = self.getConvocados()
        usuarios = usuarios + self.getConvidados()
        contatos = self.getContatos()
        fundo = self.getFundo()

        subject = "Convocação para reuniao"
        mailText = self.reuniao_send_mail(self, reuniao=self, contatos=contatos, fundo=fundo)

        for u in usuarios:
            email = portal_membership.getMemberById(u).getProperty('email', '')
            if email: self.sendNotificationEmail(email, subject, mailText)



registerType(Reuniao, PROJECTNAME)
# end of class Reuniao

##code-section module-footer #fill in your manual code here
##/code-section module-footer



